All Pairs Shortest Path

모든 쌍의 최단 경로
단일 출발점 최단 경로 알고리즘을 #V번 수행하면, 모든 쌍에 대한 최단 경로를 구할 수 있다.

벨만 포드 알고리즘을 사용하는 경우 O(V^2E)의 시간 복잡도를 가짐
(밀도가 높은 그래프의 경우 최대 O(V^4)의 시간복잡도를 가진다.)
#E<=#V(#V-1)
아래의 곱하기 연산 및 더하기 연산에서 무한대(infinity)에 대한 연산은 고려하지 않음
수정하고 사용할 것
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define NIL -1
struct Matrix{
int n;
int** value;
Matrix(int _n): n(_n){
this->value=new int*[this->n];
for(int i=0; i<this->n; ++i) this->value[i]=new int[this->n];
}
~Matrix(){
for(int i=0; i<this->n; ++i) delete value[i];
delete[] value;
}
Matrix& operator=(const Matrix& other) {
this->n=other.n;
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j) this->Set(i, j, other.Value(i, j));
}
return *this;
}
int Value(int i, int j) const {
assert(i<this->n && j<this->n);
return value[i][j];
}
void Set(int i, int j, int x){
assert(i<this->n && j<this->n);
value[i][j]=x;
}
};
void PrintPI(Matrix* PI, int i, int j){
if(i==j) std::cout<<i<<' '<<std::endl;
else if(PI->Value(i, j)==NIL){
perror("NO ROUTE");
exit(1);
} else {
PrintPI(PI, i, PI->Value(i, j));
std::cout<<j<<' ';
}
}
Matrix ExtendShortestPaths(Matrix* L, Matrix* W){
int n=L->n;
Matrix nL(n);
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j){
nL.Set(i, j, INT_MAX);
for(int k=0; k<n; ++k){
int tmp=std::min(nL.Value(i, j), L->Value(i, k)+W->Value(k, j));
nL.Set(i, j,tmp);
}
}
}
return nL;
}
Matrix SquareMatrixMultiply(const Matrix* A, const Matrix* B){
int n=A->n;
Matrix C(n);
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j){
int tmp=0;
for(int k=0; k<n; ++k){
tmp+=A->Value(i, j)*B->Value(i, j);
C.Set(i, j, tmp);
}
}
}
return C;
}
Matrix ShowAllPairsShortestPaths(Matrix* W){
int n=W->n;
Matrix L=*W;
for(int m=2; m<n-2; ++m){
Matrix L=ExtendShortestPaths(&L, W);
}
return L;
}
l(m)ij=min(lm1ij,min1kn{l(m1)ik+wkj) m: 정점 i, 정점 j까지의 간선 개수 L(m1)는 실제 최단 경로 가중치를 가짐